package com.guodi.model.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.guodi.common.constant.StatusCode;
import com.guodi.common.utils.AjaxResult;
import com.guodi.common.utils.PageData;
import com.guodi.common.utils.UuidUtil;
import com.guodi.core.boot.ctrl.BaseController;
import com.guodi.core.minio.util.MinioUtil;
import com.guodi.core.secure.utils.AuthUtil;
import com.guodi.core.tool.api.R;
import com.guodi.map.feign.IMapClient;
import com.guodi.model.dto.IdtEstimateResultDto;
import com.guodi.model.entity.*;
import com.guodi.model.service.*;
import com.guodi.model.utils.ExcelUtil;
import com.guodi.model.utils.RecursionUtils;
import com.guodi.model.utils.TimeUtils;
import com.guodi.model.vo.ApiIndicatorsValue;
import com.guodi.system.feign.ISysClient;
import com.guodi.system.feign.IUserClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import java.io.*;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @描述：指标目录表控制类
 * @作者: 彭辉
 * @日期: 2020-06-05
 */

@RestController
@RequestMapping("/IdtIndicatorsDir")
@Api(value = "API - IdtIndicatorsDirController", description = "指标目录表")
public class IdtIndicatorsDirController extends BaseController {

    @Resource
    public IIdtIndicatorsDirService idtIndicatorsDirService;

    @Resource
    private IIdtIndicatorsService iIdtIndicatorsService;

    @Resource
    private IIdtIndicatorsTypeService iIdtIndicatorsTypeService;

    @Resource
    private IIdtWarnRuleService iIdtWarnRuleService;

    @Resource
    private IIdtMonitorValueService iIdtMonitorValueService;

    @Resource
    private IIdtReportValueService idtReportValueService;

    @Resource
    private IRedisDictService iRedisDictService;

    @Resource
    private IUserClient iUserClient;

    @Resource
    private ISysClient iSysClient;

    @Resource
    private IIdtReportFillService iIdtReportFillService;

    @Resource
    private IIdModelLayerService iIdModelLayerService;

    @Resource
    private IIdtValueExportService iIdtValueExportService;

    @Resource
    private IMapClient mapClient;

    //指标图片存储路径
    private static String IDT_PIC_PATH = "IdtIndicators/images/";

    @Value("${minio.bucketName}")
    private String bucketName;


    /**
     * @描述: 根据指标体系的id获取关联的指标树，不会带任何数值
     * @入参:
     * @出参:
     * @作者: 陈宏成
     * @日期: 2020-06-05
     **/
    @PostMapping("/treeByIdtTypeId")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "idtTypeId", value = "指标体系的id", required = true, dataType = "string", paramType = "query")
    })
    @ApiOperation(value = "根据指标体系的id获取关联的指标树，不会带任何数值")
    public AjaxResult treeByIdtTypeId(@NotBlank(message = "请选择一个指标体系") String idtTypeId) {
        //获取根据编码获取体系类型
        IdtIndicatorsType one = iIdtIndicatorsTypeService.getById(idtTypeId);
        if(null == one){
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "指标体系");
        }
        //获取父节点下的所有数据
        List<ApiIdtIndicatorsDir> treeList = idtIndicatorsDirService.listDirByCode(one.getId(), null, null);

        //创建树形结构
        List tree = createTree(one.getId(), treeList);
        return new AjaxResult(tree);
    }

    /**
     * @描述: 根据实体属性分页查询
     * @入参:
     * @出参:
     * @作者: 彭辉
     * @日期: 2020-06-05
     **/
    @PostMapping("/listByEntity")
    @ApiOperation(value = " 根据实体属性分页查询")
    public AjaxResult listByEntity(Page page, IdtIndicatorsDir idtIndicatorsDir) {
        LambdaQueryWrapper<IdtIndicatorsDir> wrapper = new QueryWrapper().lambda();
        IPage<IdtIndicatorsDir> iPage = idtIndicatorsDirService.page(page, wrapper);
        return new AjaxResult(iPage);
    }

    /**
     * @描述: 根据主键查询
     * @入参:
     * @出参:
     * @作者: 彭辉
     * @日期: 2020-06-05
     **/
    @PostMapping("/findById")
    @ApiOperation(value = "根据主键查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = true,
                    dataType = "string", paramType = "query")
    })
    public AjaxResult findById(String id) {
        if (StringUtils.isBlank(id)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "id不能为空");
        }
        IdtIndicatorsDir idtIndicatorsDir = idtIndicatorsDirService.getById(id);
        return new AjaxResult(idtIndicatorsDir);
    }

    /**
     * @描述: 新增
     * @入参:
     * @出参:
     * @作者: 彭辉
     * @日期: 2020-06-05
     **/
    @PostMapping("/save")
    @ApiOperation(value = "新增")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "名称", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "displayContent", value = "展示内容", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "parentId", value = "上级目录Id", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "indicatorsId", value = "指标id,多个用,隔开", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "relFormJson", value = "关联指标项字符串", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "indicatorsTypeId", value = "目录所属指标体系Id", dataType = "string", paramType = "query")
    })
    public synchronized AjaxResult save(IdtIndicatorsDir idtIndicatorsDir) {
        String deptId = this.getUser().getDeptId();
        if (StringUtils.isBlank(deptId)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "改用户所属部门不存在");
        }
        if (StringUtils.isBlank(idtIndicatorsDir.getParentId())) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "传入的父节点不能为空");
        }
        LambdaQueryWrapper<IdtIndicatorsDir> queryWrapper = new QueryWrapper().lambda();
        queryWrapper.eq(IdtIndicatorsDir::getParentId, idtIndicatorsDir.getParentId());
        queryWrapper.eq(IdtIndicatorsDir::getName, idtIndicatorsDir.getName());
        List<IdtIndicatorsDir> idtIndicatorsDirList = idtIndicatorsDirService.list(queryWrapper);
        if (idtIndicatorsDirList.size() > 0) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "该名称已经存在,请更换");
        }
        prepareData(idtIndicatorsDir, true);
        idtIndicatorsDir.setId(UuidUtil.get32UUID());
//        if (idtIndicatorsDir.getSort() == null) {
//            idtIndicatorsDir.setSort(idtIndicatorsDirService.selectMaxSort() + 1);
//        }
        String relFormJson = idtIndicatorsDir.getRelFormJson();
        if (StringUtils.isBlank(relFormJson)) {
            if (StringUtils.isBlank(idtIndicatorsDir.getName())) {
                return new AjaxResult(StatusCode.ERROR_CODE_40005, "传入的目录/指标名称不能为空");
            }
            idtIndicatorsDir.setType(1);
            idtIndicatorsDir.setOrgId(deptId);
            boolean bol = idtIndicatorsDirService.save(idtIndicatorsDir);
            if (bol) {
                List<IdtIndicatorsDir> list11 = new ArrayList<>();
                list11.add(idtIndicatorsDir);
                return new AjaxResult(list11);
            } else {
                return new AjaxResult(StatusCode.REQUEST_CODE_OPERATION_FAILURE, "保存失败");
            }
        } else {
            List<JSONObject> formList = JSONObject.parseArray(relFormJson, JSONObject.class);
            Map<String, JSONObject> updateMap = new HashMap<>();
            for (JSONObject jsonObject : formList) {
                String key = jsonObject.getString("indicatorsCustomCode");
                updateMap.put(key, jsonObject);
            }
            // 新增信息时，需要对关联指标的自定义编码进行唯一值过滤
            List<IdtIndicatorsDir> indicatorsDbList = idtIndicatorsDirService.getAllByParentId(idtIndicatorsDir.getIndicatorsTypeId(), null);
            for (IdtIndicatorsDir idtDir : indicatorsDbList) {
                // 判断是否是指标项
                if (idtDir.getType() == 2) {
                    if (updateMap.get(idtDir.getIndicatorsCustomCode()) != null && !updateMap.get(idtDir.getIndicatorsCustomCode()).get("indicatorsId").equals(idtDir.getIndicatorsId())) {
                        return new AjaxResult(StatusCode.ERROR_CODE_40005, "自定义指标编码：" + idtDir.getIndicatorsCustomCode() + "已经存在，不可重复添加");
                    }
                }
            }
            List<String> indicatorsIds = new ArrayList<>();
            for (JSONObject object : formList) {
                indicatorsIds.add(object.getString("indicatorsId"));
            }
            List<IdtIndicators> list_ids = iIdtIndicatorsService.listByIds(indicatorsIds);
            List<IdtIndicatorsDir> list = new ArrayList<>();
            Integer sort = idtIndicatorsDirService.selectMaxSort();
            for (int i = 0; i < formList.size(); i++) {
                for (int j = 0; j < list_ids.size(); j++) {
                    IdtIndicators idtIndicators = list_ids.get(j);
                    if (idtIndicators.getId().equals(formList.get(i).getString("indicatorsId"))) {
                        //获取指标详细信息
                        IdtIndicatorsDir newIdtIndicatorsDir = new IdtIndicatorsDir();
                        prepareData(newIdtIndicatorsDir, true);
                        newIdtIndicatorsDir.setId(UuidUtil.get32UUID());
                        newIdtIndicatorsDir.setName(idtIndicators.getName());

                        newIdtIndicatorsDir.setParentId(idtIndicatorsDir.getParentId());
                        newIdtIndicatorsDir.setType(2);
                        newIdtIndicatorsDir.setDisplayContent(idtIndicatorsDir.getDisplayContent());
                        newIdtIndicatorsDir.setIcon(idtIndicatorsDir.getIcon());
                        if (idtIndicatorsDir.getSort() == null) {
                            //防止批量添加时只有一个顺序
                            newIdtIndicatorsDir.setSort(++sort);
//                            newIdtIndicatorsDir.setSort(idtIndicatorsDirService.selectMaxSort() + 1);
                        } else {
                            newIdtIndicatorsDir.setSort(idtIndicatorsDir.getSort());
                        }
                        newIdtIndicatorsDir.setRemark(idtIndicators.getRemark());
                        // 指标主键
                        newIdtIndicatorsDir.setIndicatorsId(formList.get(i).getString("indicatorsId"));
                        // 指标自定义编码
                        newIdtIndicatorsDir.setIndicatorsCustomCode(formList.get(i).getString("indicatorsCustomCode"));
                        //额外字段添加
                        newIdtIndicatorsDir.setIdtName(idtIndicators.getName());
                        newIdtIndicatorsDir.setIdtCode(idtIndicators.getCode());
                        newIdtIndicatorsDir.setIdtUnit(idtIndicators.getUnit());
                        newIdtIndicatorsDir.setIdtAttribute(idtIndicators.getAttribute());
                        newIdtIndicatorsDir.setIdtDatasource(idtIndicators.getDatasource());
                        newIdtIndicatorsDir.setIdtDivisionCode(idtIndicators.getDivisionCode());
                        newIdtIndicatorsDir.setIdtIsPublic(idtIndicators.getIsPublic());
                        newIdtIndicatorsDir.setIdtScope(idtIndicators.getScope());
                        newIdtIndicatorsDir.setIdtType(idtIndicators.getType());
                        newIdtIndicatorsDir.setOrgId(deptId);
                        list.add(newIdtIndicatorsDir);
                    }
                }
            }
            boolean bol = idtIndicatorsDirService.saveBatch(list);
            if (bol) {
                return new AjaxResult(list);
            } else {
                return new AjaxResult(StatusCode.REQUEST_CODE_OPERATION_FAILURE, "保存失败");
            }
        }
    }

    /**
     * @描述: 修改
     * @入参:
     * @出参:
     * @作者: 彭辉
     * @日期: 2020-06-05
     **/
    @PostMapping("/update")
    @ApiOperation(value = "修改")
    public AjaxResult update(IdtIndicatorsDir idtIndicatorsDir, String deleteFileStr, @RequestParam(required = false, value = "file") MultipartFile file) {
        String deptId = this.getUser().getDeptId();
        if (StringUtils.isBlank(deptId)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "该用户所属部门不存在");
        }
        if (StringUtils.isBlank(idtIndicatorsDir.getId())) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "请传入必要id");
        }
        LambdaQueryWrapper<IdtIndicatorsDir> queryWrapper = new QueryWrapper().lambda();
        queryWrapper.eq(IdtIndicatorsDir::getParentId, idtIndicatorsDir.getParentId());
        queryWrapper.eq(IdtIndicatorsDir::getName, idtIndicatorsDir.getName());
        queryWrapper.ne(IdtIndicatorsDir::getId, idtIndicatorsDir.getId());
        List<IdtIndicatorsDir> idtIndicatorsDirList = idtIndicatorsDirService.list(queryWrapper);
        if (idtIndicatorsDirList.size() > 0) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "该目录名称已经存在");
        }
        //获取原始数据
        IdtIndicatorsDir ysIndicatorsDir = idtIndicatorsDirService.getById(idtIndicatorsDir.getId());
        if (ysIndicatorsDir == null) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "请检查传入的id是否正确");
        }
        if (ysIndicatorsDir.getType() == 2 && StringUtils.isNotBlank(idtIndicatorsDir.getIndicatorsId()) && !ysIndicatorsDir.getIndicatorsId().equals(idtIndicatorsDir.getIndicatorsId())) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "不能更改该指标id");
        }
        if (StringUtils.isNotBlank(idtIndicatorsDir.getRelFormJson())) {
            List<JSONObject> formList = JSONObject.parseArray(idtIndicatorsDir.getRelFormJson(), JSONObject.class);
            Map<String, JSONObject> updateMap = new HashMap<>();
            for (JSONObject jsonObject : formList) {
                String key = jsonObject.getString("indicatorsCustomCode");
                updateMap.put(key, jsonObject);
            }
            // 新增信息时，需要对关联指标的自定义编码进行唯一值过滤
            List<IdtIndicatorsDir> indicatorsDbList = idtIndicatorsDirService.getAllByParentId(idtIndicatorsDir.getIndicatorsTypeId(), null);
            for (IdtIndicatorsDir idtDir : indicatorsDbList) {
                // 判断是否是指标项
                if (idtDir.getType() == 2) {
                    if (updateMap.get(idtDir.getIndicatorsCustomCode()) != null && !updateMap.get(idtDir.getIndicatorsCustomCode()).get("indicatorsId").equals(idtDir.getIndicatorsId())) {
                        return new AjaxResult(StatusCode.ERROR_CODE_40005, "自定义指标编码：" + idtDir.getIndicatorsCustomCode() + "已经存在，不可重复添加");
                    }
                }
            }
        }
        prepareData(idtIndicatorsDir, false);
        idtIndicatorsDir.setOrgId(deptId);
        // 2020-10-26 新增图片上传功能
        if (file != null) {
            // 存储文件
            try {
                if(StringUtils.isNotBlank(ysIndicatorsDir.getUploadFile())){
//                    String group = ysIndicatorsDir.getUploadFile().substring(0, ysIndicatorsDir.getUploadFile().indexOf("/"));
                    MinioUtil.delete(bucketName, ysIndicatorsDir.getUploadFile());
                }
//                String fileFormat = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
                String filePath = MinioUtil.uploadFile(file.getInputStream(), IDT_PIC_PATH + idtIndicatorsDir.getId() + "/" + file.getOriginalFilename());
                idtIndicatorsDir.setUploadFile(filePath);
            } catch (IOException e) {
                return new AjaxResult(StatusCode.REQUEST_CODE_ERROR, "上传文件失败！");
            }
        }else {
            if ("1".equals(deleteFileStr)){//点击删除时前端传一个状态
                if(StringUtils.isNotBlank(ysIndicatorsDir.getUploadFile())){
//                    String group = ysIndicatorsDir.getUploadFile().substring(0, ysIndicatorsDir.getUploadFile().indexOf("/"));
                    MinioUtil.delete(bucketName, ysIndicatorsDir.getUploadFile());
                    idtIndicatorsDir.setUploadFile("");
                }
            }else {
                idtIndicatorsDir.setUploadFile(ysIndicatorsDir.getUploadFile());
            }
        }
        // 20230424 新增评估规则配置字段
        if(StringUtils.isNotBlank(idtIndicatorsDir.getWarnRuleConfig())){
            idtIndicatorsDir.setWarnRuleConfig(StringEscapeUtils.unescapeXml(idtIndicatorsDir.getWarnRuleConfig()));
        }
        if(StringUtils.isNotBlank(idtIndicatorsDir.getEstimateRuleConfig())){
            idtIndicatorsDir.setEstimateRuleConfig(StringEscapeUtils.unescapeXml(idtIndicatorsDir.getEstimateRuleConfig()));
        }
        boolean bol = idtIndicatorsDirService.updateById(idtIndicatorsDir);
        if (bol) {
            return new AjaxResult(idtIndicatorsDir);
        } else {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "id不能为空");
        }
    }

    /**
     * @描述: 根据主键删除
     * @入参: id
     * @出参:
     * @作者: 彭辉
     * @日期: 2020-06-05
     **/
    @PostMapping("/delete")
    @ApiOperation(value = "根据主键删除")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = true,
                    dataType = "string", paramType = "query")
    })
    public AjaxResult delete(String id) {
        if (StringUtils.isBlank(id)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "id不能为空");
        }
        //获取待删除类型为指标的数据集合
        List<String> list = idtIndicatorsDirService.findById(id);
        if (list.size() > 0) {
            LambdaQueryWrapper<IdtIndicatorsDir> lambdaQueryWrapper = new LambdaQueryWrapper();
            lambdaQueryWrapper.in(IdtIndicatorsDir::getId, list);
            List<IdtIndicatorsDir> dirList = idtIndicatorsDirService.list(lambdaQueryWrapper);
            //删除文件信息
            for (IdtIndicatorsDir ids : dirList) {
                if(StringUtils.isNotBlank(ids.getUploadFile())){
//                    String group = ids.getUploadFile().substring(0, ids.getUploadFile().indexOf("/"));
                    MinioUtil.delete(bucketName, ids.getUploadFile());
                }
            }
        }
        //递归删除数据
        idtIndicatorsDirService.deleteByIds(id);
        return new AjaxResult();
    }

    /**
     * @描述:根据id批量删除
     * @入参:
     * @出参:
     * @作者: 戴伙进
     * @日期: 2020/6/10 16:39
     **/
    @PostMapping("/deleteByIds")
    @ApiOperation(value = "根据主键数组删除")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "传入的是一个JSON数组", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult deleteByIds(String ids) {
        if (StringUtils.isBlank(ids)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "ids不能为空");
        }
        JSONArray jsonArray = JSONObject.parseArray(ids);
        List<String> list = JSONObject.parseArray(jsonArray.toJSONString(), String.class);
        idtIndicatorsDirService.removeByIds(list);
        if (list != null) {
            LambdaQueryWrapper<IdtIndicatorsDir> lambdaQueryWrapper = new LambdaQueryWrapper();
            lambdaQueryWrapper.in(IdtIndicatorsDir::getId, list);
            List<IdtIndicatorsDir> dirList = idtIndicatorsDirService.list(lambdaQueryWrapper);
            //删除文件信息
            for (IdtIndicatorsDir dir : dirList) {
                if(StringUtils.isNotBlank(dir.getUploadFile())){
                    String group = dir.getUploadFile().substring(0, dir.getUploadFile().indexOf("/"));
//                    FastDFSUtil.delete(group, dir.getUploadFile());
                    MinioUtil.delete(bucketName, dir.getUploadFile());
                }
            }
        }
        return new AjaxResult();
    }

    public static void sortList(List<ApiIdtIndicatorsDir> list, List<ApiIdtIndicatorsDir> resultList, String id) {
        for (ApiIdtIndicatorsDir node : list) {
            if (node.getParentId().equals(id)) {
                node.setTreeLevel(node.getTreeLevel() + 1);
                resultList.add(node);
                sortList(list, resultList, node.getId());
            }
        }
    }

    /**
     * @描述:获取所有的递归树的列表
     * @入参:
     * @出参:
     * @作者: 戴伙进
     * @日期: 2020/6/4 15:24
     **/
    @PostMapping("/listAllByParentId")
    @ApiOperation(value = "通过父节点获取列表数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "parentId", value = "父节点", required = true,
                    dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "searchType", value = "查询类型（1：关联图层查询）",
                    dataType = "string", paramType = "query")
    })
    public AjaxResult listAllByParentId(String parentId, String searchType) {
        String deptId = AuthUtil.getDeptId();
        if (StringUtils.isBlank(deptId)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "该用户所属部门不存在");
        }
        if (StringUtils.isBlank(parentId)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "请传入父节点");
        }
        //获取单位id
        String orgId = deptId;
        //获取父节点下的所有数据
        List<IdtIndicatorsDir> treeList = idtIndicatorsDirService.getAllByParentId(parentId, null);
        if ("1".equals(searchType)) {
            List<IdtModelLayer> relLayerList = iIdModelLayerService.getListBySystemId(parentId);
            for (IdtModelLayer idtModelLayer : relLayerList) {
                IdtIndicatorsDir idtIndicatorsDir = new IdtIndicatorsDir();
                idtIndicatorsDir.setId(idtModelLayer.getId());
                idtIndicatorsDir.setParentId(idtModelLayer.getParentId());
                idtIndicatorsDir.setName(idtModelLayer.getLayerName());
                idtIndicatorsDir.setAlias(idtModelLayer.getAlias());
                idtIndicatorsDir.setType(3);
                idtIndicatorsDir.setSort(idtModelLayer.getSort());
                idtIndicatorsDir.setIdtModelLayer(idtModelLayer);
                treeList.add(idtIndicatorsDir);
            }
        }
        List<IdtIndicatorsDir> resultList = new ArrayList<>();
        //进行排序
        sortList(treeList, parentId, resultList, null);
        // sortList(treeList, parentId, resultList);
        return new AjaxResult(resultList);

    }

    /**
     * @描述:通过父节点获取列表数据
     * @入参:
     * @出参:
     * @作者: 郑文彬
     * @日期: 2020/6/29 15:40
     **/
    @PostMapping("/listAllByCode")
    @ApiOperation(value = "通过父节点获取列表数据(指标体系)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "指标体系编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "isQueryValue", value = "是否查询指标数值", required = true, dataType = "boolean", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "区域编码（查询指标数值时需要传）", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "divisionName", value = "区域名称", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "year", value = "指标数值年份（查询指标数值时需要传）", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "startYear", value = "起始年份", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "endYear", value = "结束年份", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "keyword", value = "关键字搜索", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "orgId", value = "机构id(65fc1451aa4640c795b971ae9199456c)", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "isCountType", value = "是否统计不同类型的指标数量，默认不统计", dataType = "boolean", paramType = "query"),
            @ApiImplicitParam(name = "particularYear", value = "指标体系年份", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult listAllByCode(String code, boolean isQueryValue, String divisionCode, String startYear, String endYear,
                                    String year, String orgId, String keyword, String divisionName, Boolean isCountType, String particularYear) {
        if (StringUtils.isBlank(code)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "请传入编码点");
        }
//        if (StringUtils.isBlank(orgId)) {
//            return new AjaxResult(StatusCode.ERROR_CODE_40005, "请传入机构点");
//        }
        if ( isQueryValue && StringUtils.isBlank(divisionCode)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "查询指标数值时区域编码必传");
        }
        if ( isQueryValue && StringUtils.isBlank(year) && (StringUtils.isBlank(startYear) || StringUtils.isBlank(endYear))) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "查询指标数值时年份必传");
        }
        //获取根据编码获取体系类型
        IdtIndicatorsType one = iIdtIndicatorsTypeService.findByCode(code, particularYear, divisionCode);
        if(null == one){
            return new AjaxResult();
        }
        //获取父节点下的所有数据
        List<ApiIdtIndicatorsDir> treeList = idtIndicatorsDirService.listDirByCode(one.getId(), null, null);
        //按关键字（名称）过滤最后一级
        if (StringUtils.isNotBlank(keyword)) {

            Iterator<ApiIdtIndicatorsDir> iterator = treeList.iterator();
            while (iterator.hasNext()) {
                ApiIdtIndicatorsDir idtDir = iterator.next();
                if (idtDir.getType() == 2) {
                    if (!idtDir.getName().contains(keyword)) {
                        iterator.remove();
                        continue;
                    }
                }
            }
        }
        /*if(StringUtils.isNotBlank(area_code)) {
            Iterator<ApiIdtIndicatorsDir> iterator = treeList.iterator();
            while (iterator.hasNext()) {
                ApiIdtIndicatorsDir idtDir = iterator.next();
                if (idtDir.getType() == 2) {
                    if (StringUtils.isNotBlank(idtDir.getIdtDivisionCode()) && !idtDir.getIdtDivisionCode().contains(area_code)) {
                        iterator.remove();
                        continue;
                    }
                }
            }
        }*/
        if (isQueryValue && treeList != null && treeList.size() > 0) {

            // 过滤掉关联的指标已经被删除了的记录
            LambdaQueryWrapper<IdtIndicators> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.select(IdtIndicators::getId);
            List<Map<String, Object>> maps = this.iIdtIndicatorsService.listMaps(queryWrapper);
            List<String> allIdtIdList = maps.stream().map(map -> {
                return map.containsKey("id") ? map.get("id").toString() : map.get("ID").toString();
            }).collect(Collectors.toList());
            treeList = treeList.parallelStream().filter(dir->{
                return dir.getType() != 2 ? true: allIdtIdList.contains(dir.getIndicatorsId());
            }).collect(Collectors.toList());
            // 过滤出指标
            List<ApiIdtIndicatorsDir> idtList = treeList.stream().filter(idtDir -> {
                return idtDir.getType() == 2;
            }).collect(Collectors.toList());
            // 如果指标没有，那么直接返回
            if (idtList == null || idtList.isEmpty()){
                return new AjaxResult(createTree(one.getId(), treeList));
            }
            // 查询因子的指标值
            // 因子列表
            List<ApiIdtIndicatorsDir> relIdtList = new LinkedList<>();
            // 因子id列表
            List<String> relIdtIdList = new LinkedList<>();
            // 查询所有指标
            List<IdtIndicators> allIdtList = iIdtIndicatorsService.list();
            // 获取复合指标下的单一指标
            for (ApiIdtIndicatorsDir apiIdtIndicatorsDir : treeList) {
                for (IdtIndicators idtIndicator : allIdtList) {
                    // 条件：指标类型 + 计算公式不为空 + 计算公式包含这个指标
                    if (apiIdtIndicatorsDir.getType() == 2 && StringUtils.isNotBlank(apiIdtIndicatorsDir.getCalculateResult())
                            && apiIdtIndicatorsDir.getCalculateResult().indexOf(idtIndicator.getCode()) !=  -1) {
                        List<ApiIdtIndicatorsDir> calculateResultLit = null;
                        if (apiIdtIndicatorsDir.getCalculateResultLit() == null) {
                            calculateResultLit = new ArrayList<>();
                        } else {
                            calculateResultLit = apiIdtIndicatorsDir.getCalculateResultLit();
                        }
                        ApiIdtIndicatorsDir relDir = new ApiIdtIndicatorsDir();
                        relDir.setId(idtIndicator.getId());
                        relDir.setIndicatorsId(idtIndicator.getId());
                        relDir.setType(2);
                        relDir.setIdtCalculateSource(apiIdtIndicatorsDir.getIdtCalculateSource());
                        relDir.setIdtConnotation(idtIndicator.getConnotation());
                        relDir.setIdtCode(idtIndicator.getCode());
                        relDir.setIdtCalculateUnit(idtIndicator.getCalculateUnit());
                        relDir.setIdtDutyDepartment(idtIndicator.getDutyDepartment());
                        relDir.setIdtDutyCompany(idtIndicator.getDutyCompany());
                        relDir.setIdtDatasource(idtIndicator.getDatasource());
                        relDir.setIdtDivisionCode(idtIndicator.getDivisionCode());
                        relDir.setIdtName(idtIndicator.getName());
                        relDir.setIdtScope(idtIndicator.getScope());
                        relDir.setIdtType(idtIndicator.getType());
                        relDir.setIdtUnit(idtIndicator.getUnit());
                        relDir.setName(idtIndicator.getName());
                        calculateResultLit.add(relDir);
                        apiIdtIndicatorsDir.setCalculateResultLit(calculateResultLit);
                        // 加入因子列表
                        relIdtList.add(relDir);
                        relIdtIdList.add( relDir.getIndicatorsId() );
                    }
                }
            }
            if (!relIdtIdList.isEmpty()){
                // 查指标数值
                Map<String, List<ApiIndicatorsVal>> relIdtValMap;
                if (StringUtils.isNotBlank(startYear) && StringUtils.isNotBlank(endYear)) {
                    // 查询指标数值
                    relIdtValMap = iIdtIndicatorsService.mapIdtVal(relIdtIdList, startYear, endYear, divisionCode, false, false);
                }else{
                    relIdtValMap = iIdtIndicatorsService.mapIdtVal(relIdtIdList, year, divisionCode, false, false);
                }
                // 填入因子列表
                relIdtList.stream().forEach(relDir->{
                    List<ApiIndicatorsVal> apiIndicatorsValList = relIdtValMap.get(relDir.getIndicatorsId());
                    if (StringUtils.isNotBlank(startYear) && StringUtils.isNotBlank(endYear)) {
                        relDir.setApiIndicatorsValList(apiIndicatorsValList);
                    }else{
                        relDir.setApiIndicatorsVal(apiIndicatorsValList.isEmpty()? null: apiIndicatorsValList.get(0));
                    }
                });
            }
            // 获取所有指标
            List<String> idtIdList = treeList.stream().filter(idtDir -> {
                return idtDir.getType() == 2;
            }).map(ApiIdtIndicatorsDir::getIndicatorsId).collect(Collectors.toList());
            // 查指标数值
            Map<String, List<ApiIndicatorsVal>> idtValMap;
            if (StringUtils.isNotBlank(startYear) && StringUtils.isNotBlank(endYear)) {
                // 查询指标数值
                idtValMap = iIdtIndicatorsService.mapIdtVal(idtIdList, startYear, endYear, divisionCode, false, false);
            }else{
                idtValMap = iIdtIndicatorsService.mapIdtVal(idtIdList, year, divisionCode, false, false);
            }
            // 填入对象中
            idtList.forEach(idtDir -> {
                List<ApiIndicatorsVal> apiIndicatorsValList = idtValMap.get(idtDir.getIndicatorsId());
                if (StringUtils.isNotBlank(startYear) && StringUtils.isNotBlank(endYear)) {
                    idtDir.setApiIndicatorsValList(apiIndicatorsValList);
                }else{
                    ApiIndicatorsVal apiIndicatorsVal = apiIndicatorsValList.get(0);
                    // 20210806 指标预警添加预警状态
                    if(StringUtils.isNotBlank(apiIndicatorsVal.getWarnRuleConfig())){
                        String warnStatus = iIdtIndicatorsService.updateWarnStatus(apiIndicatorsVal);
                        apiIndicatorsVal.setWarnStatus(warnStatus);
                    }else {
                        apiIndicatorsVal.setWarnStatus("null,尚未配置规则");
                    }
                    idtDir.setApiIndicatorsVal(apiIndicatorsValList.isEmpty()? null: apiIndicatorsValList.get(0));
                }
                //计算评估级别
                String estimateStatus = this.iIdtMonitorValueService.getEstimateStatus(code, idtDir.getIndicatorsId(), idtDir.getApiIndicatorsVal().getMonitorValue(), year, divisionCode);
                idtDir.getApiIndicatorsVal().setEstimateStatus(estimateStatus);
            });
        }
        // 获取所有单位，key为单位id，value为单位名称
        Map<String, String> deptMap = iIdtIndicatorsService.getDeptNameMap();
        treeList.stream().filter(idt->{
            return idt.getType() == 2;
        }).forEach(idtDir->{
            // 将责任处室返回中文
            idtDir.setIdtDutyCompanyName(deptMap.get(idtDir.getIdtDutyCompany()));
            idtDir.setIdtDutyDepartmentName(deptMap.get(idtDir.getIdtDutyDepartment()));
        });
        treeList.sort(Comparator.comparing(ApiIdtIndicatorsDir::getSort));
        //创建树形结构
        List tree = createTree(one.getId(), treeList);
        // 统计不同指标类型的数量
        if (isCountType != null && isCountType == true){
            RecursionUtils.countNum(null, tree);
        }
        return new AjaxResult(tree);
    }


    /**
     * @描述: 根据分类code查询目录下所有指标(体检评估)
     * @入参:
     * @出参:
     * @作者: 汤厚韬
     * @日期: 2021/1/7
     **/
    @PostMapping("/listByCode")
    @ApiOperation(value = "根据分类code查询目录下所有指标")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "指标体系分类code", required = false, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "name", value = "名称检索", required = false, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "行政区划代码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "dataType", value = "填报类型", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "idtTypeId", value = "指标体系ID", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult listByCode(String code, String divisionCode, String dataType, String idtType, String status, String keyWord, String idtTypeId) {
        //获取根据编码获取体系类型
        IdtIndicatorsType one = iIdtIndicatorsTypeService.getById(idtTypeId);
        if (null == one) {
            return new AjaxResult();
        }
        Integer sum = 0;
        Integer rSum = 0;
        Double scale = 0.0;
        Double rScale = 0.0;
        // 2021-01-18 产品要求根据责任权限判断
        // 1-市级机构，按责任处室。市级用户可以看到本市、下级县所填报的所有指标。只能填报本处室下的指标。
        // 2-县级机构，按责任单位。县级用户可以看到本县所填报的指标。只能填报本县下的指标。
        // 获取当前用户机构所属行政区划
        //查询列表数据
        List<ApiIdtIndicatorsDir> dbDirList = idtIndicatorsDirService.listDirByCode(one.getId(), null, null);
        //按关键字（名称）过滤最后一级
        if (StringUtils.isNotBlank(keyWord)) {
            Iterator<ApiIdtIndicatorsDir> iterator = dbDirList.iterator();
            while (iterator.hasNext()) {
                ApiIdtIndicatorsDir idtDir = iterator.next();
                if (idtDir.getType() == 2) {
                    if (!idtDir.getName().contains(keyWord) && !idtDir.getIdtCode().contains(keyWord)) {
                        iterator.remove();
                        continue;
                    }
                }
            }
        }
        if (StringUtils.isNotBlank(idtType)) {
            Iterator<ApiIdtIndicatorsDir> iterator = dbDirList.iterator();
            while (iterator.hasNext()) {
                ApiIdtIndicatorsDir idtDir = iterator.next();
                if (idtDir.getType() == 2) {
                    // basic：基本指标，recommend：推荐指标，place：地方指标
                    if (!idtDir.getIdtType().equals(idtType)) {
                        iterator.remove();
                        continue;
                    }
                }
            }
        }
        Map<String, String> deptMap = iIdtIndicatorsService.getDeptNameMap();
        // 拼接指标数据
        for (ApiIdtIndicatorsDir apiIdtIndicatorsDir : dbDirList) {
            if (StringUtils.isNotBlank(apiIdtIndicatorsDir.getIdtDutyCompany())) {
                apiIdtIndicatorsDir.setIdtDutyCompanyName(iIdtIndicatorsService.getDeptNameStr(apiIdtIndicatorsDir.getIdtDutyCompany(), deptMap));
            }
            if (StringUtils.isNotBlank(apiIdtIndicatorsDir.getIdtDutyDepartment())) {
                apiIdtIndicatorsDir.setIdtDutyDepartmentName(iIdtIndicatorsService.getDeptNameStr(apiIdtIndicatorsDir.getIdtDutyDepartment(), deptMap));
            }
            if (StringUtils.isNotBlank(apiIdtIndicatorsDir.getIndicatorsId())) {
                IdtIndicators idtIndicators = iIdtIndicatorsService.getById(apiIdtIndicatorsDir.getIndicatorsId());
                if (idtIndicators == null) {
                    apiIdtIndicatorsDir.setIdtIndicators(new IdtIndicators());
                    continue;
                }
                List<IdtReportFill> idtReportFills = iIdtReportFillService.listByData(Arrays.asList(idtIndicators.getId()), (null == divisionCode ? "441203" : divisionCode).split(","));
                if (null != idtIndicators.getUpdateReportStatus() && !idtIndicators.getUpdateReportStatus().equals("0")) {
                    if (idtReportFills.size() > 0) {
                        String explain = idtReportFills.stream().filter(x -> StringUtils.isNotBlank(x.getExplain())).map(x -> x.getExplain()).collect(Collectors.joining(";"));
                        idtIndicators.setExplain(explain);
                    }
                    rSum++;
                } else if (null != idtIndicators.getUpdateReportStatus() && idtIndicators.getUpdateReportStatus().equals("0")) {
                    sum++;
                }
                //处理责任处室多级中文名问题
                if (StringUtils.isNotBlank(idtIndicators.getDutyDepartment())) {
                    idtIndicators.setDutyDepartment(apiIdtIndicatorsDir.getIdtDutyDepartmentName());
                }
                if (StringUtils.isNotBlank(idtIndicators.getDutyCompany())) {
                    idtIndicators.setDutyCompany(apiIdtIndicatorsDir.getIdtDutyCompanyName());
                }
                if (StringUtils.isNotBlank(idtIndicators.getGatherCompany())) {
                    idtIndicators.setGatherCompany(iIdtIndicatorsService.getDeptNameStr(idtIndicators.getGatherCompany(), deptMap));
                }
                if (StringUtils.isNotBlank(idtIndicators.getCalculateUnit())) {
                    idtIndicators.setCalculateUnit(iIdtIndicatorsService.getDeptNameStr(idtIndicators.getCalculateUnit(), deptMap));
                }
                // 监测上报时获取截止日期
                if (StringUtils.isNotBlank(dataType) && dataType.equals("monitor")) {
                    // 截止时间赋值
                    if (idtIndicators.getUpdateCycle().equals("year")) {
                        idtIndicators.setCutOffDate(TimeUtils.getPreYear() + "年");
                    } else if (idtIndicators.getUpdateCycle().equals("quarter")) {
                        idtIndicators.setCutOffDate(TimeUtils.getPreQuarter() + "季度");
                    } else {
                        idtIndicators.setCutOffDate(TimeUtils.getPreMonth() + "月份");
                    }
                }
                apiIdtIndicatorsDir.setIdtIndicators(idtIndicators);
            }
        }
        if (StringUtils.isNotBlank(status)) {
            Iterator<ApiIdtIndicatorsDir> iterator = dbDirList.iterator();
            while (iterator.hasNext()) {
                ApiIdtIndicatorsDir idtDir = iterator.next();
                if (idtDir.getType() == 2) {
                    // 0：已更新，1：待更新，2：已超时
                    if (StringUtils.isNotBlank(dataType) && dataType.equals("monitor")) {
                        if (idtDir.getIdtIndicators() != null && !status.equals(idtDir.getIdtIndicators().getUpdateStatus())) {
                            iterator.remove();
                            continue;
                        }
                    } else {
                        if (idtDir.getIdtIndicators() != null && !status.equals(idtDir.getIdtIndicators().getUpdateReportStatus())) {
                            iterator.remove();
                            continue;
                        }
                    }
                }
            }
        }
        List<ApiIdtIndicatorsDir> idtIndicatorsDirs = new ArrayList<>();
        // dataType monitor：监测上报，需要过滤手动更新指标
        idtIndicatorsDirs = dbDirList;
        if (StringUtils.isNotBlank(dataType) && dataType.equals("monitor")) {
            Iterator<ApiIdtIndicatorsDir> iterator = idtIndicatorsDirs.iterator();
            while (iterator.hasNext()){
                ApiIdtIndicatorsDir next = iterator.next();
                // 指标更新类型（0：自动更新，1：手动更新）,删除指标类型为模型结果的
                 if(next.getIdtIndicators() != null && next.getIdtIndicators().getUpdateType() != null
                         && next.getIdtIndicators().getUpdateType() != 1 && (next.getIdtIndicators().getUpdateType() == 0 && "model".equalsIgnoreCase(next.getIdtIndicators().getDatasource()))){
                    iterator.remove();
                 }
                // 注：2021-04-08 18:03 要求监测值填报时，只返回手动录入的，公式更新和自动更新的均屏蔽
                /*if (next.getType() == 2){
                    if (next.getIdtIndicators() == null || StringUtils.isBlank(next.getIdtIndicators().getDatasource())
                            || !"hand".equalsIgnoreCase(next.getIdtIndicators().getDatasource())){
                        iterator.remove();
                    }
                }*/
            }
        } /*else {
            List<String> deptIdList = new ArrayList<>();
            String deptId = this.getUser().getDeptId();
            deptIdList.add(deptId);
            List<Dept> deptList = iSysClient.getDeptChild(Long.valueOf(deptId)).getData();
            for (Dept dept : deptList) {
                String dutyDepartment = dept.getId().toString();
                deptIdList.add(dutyDepartment);
            }
            for (String dutyDepartment : deptIdList) {
                for (ApiIdtIndicatorsDir apiIdtIndicatorsDir : dbDirList) {
                    if (apiIdtIndicatorsDir.getType() == 1 || (apiIdtIndicatorsDir.getType() == 2 && StringUtils.isNotBlank(apiIdtIndicatorsDir.getIdtDutyDepartment())
                            && (apiIdtIndicatorsDir.getIdtDutyDepartment().indexOf(dutyDepartment) != -1))) {
                        if (!idtIndicatorsDirs.contains(apiIdtIndicatorsDir)) {
                            idtIndicatorsDirs.add(apiIdtIndicatorsDir);
                        }
                    }
                }
            }
            // 判断用户机构级别--20210701需求变更
            *//*switch (divisionCode.length()) {
                case (2):
                    break;
                case (4):
                    // 市级根据处室判断是否可以上报。
                    idtIndicatorsDirs.stream().map(p-> {
                        if (StringUtils.isNotBlank(p.getIdtDutyDepartment()) && p.getIdtDutyDepartment().indexOf(deptId) != -1) {
                            p.setIsReportFlag(1);
                        } else {
                            p.setIsReportFlag(0);
                        }
                        return p;
                    }).collect(Collectors.toList());
                    break;
                case (6):
                    // 区县按照单位判断是否可以上报。
                    idtIndicatorsDirs.stream().map(p-> {
                        if (StringUtils.isNotBlank(p.getIdtDutyDepartment()) && p.getIdtDutyDepartment().indexOf(deptId) != -1) {
                            p.setIsReportFlag(1);
                        } else {
                            p.setIsReportFlag(0);
                        }
                        return p;
                    }).collect(Collectors.toList());
                    break;
                case (9):
                    break;
                default:
                    break;
            }*//*
        }*/
        // 20210701--根据操作项角色权限控制是否可上报 --20210721去掉这块逻辑
        /*idtIndicatorsDirs.parallelStream().forEach(x ->{
            if(StringUtils.isNotBlank(x.getIdtDutyDepartment())){
                List<Long> userIds = new ArrayList<>();
                List<UserVO> userVOS = iUserClient.findAllUserByDeptIds(x.getIdtDutyDepartment()).getData();
                List<Long> currentUserIds = userVOS.stream().map(u->u.getId()).collect(Collectors.toList());
                userIds.addAll(currentUserIds);
                x.setUserIds(userIds);
            }
        });*/
        List<ApiIdtIndicatorsDir> resultList = new ArrayList<>();
        sortList(idtIndicatorsDirs, resultList, one.getId());
        if (sum > 0 || rSum > 0) {
            Integer all = sum + rSum;
            DecimalFormat df = new DecimalFormat("#.00");
            scale = Double.valueOf(df.format((double) sum / (double) all * 100));
            rScale = Double.valueOf(df.format((double) rSum / (double) all * 100));
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("idtIndicatorsDirs", resultList);
        jsonObject.put("rScale", rScale);
        jsonObject.put("rSum", rSum);
        jsonObject.put("scale", scale);
        jsonObject.put("sum", sum);
        return new AjaxResult(jsonObject);
    }


    /**
     * @描述: 体检评估(评估数值)
     * @入参:
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2020/11/19 15:01
     **/
    @PostMapping("/listDataByCode")
    @ApiOperation(value = "体检评估(评估数值)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "指标体系编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "区域编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "year", value = "指标数值年份（多值使用逗号隔开）", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "keyword", value = "关键字搜索", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "orgId", value = "机构id(65fc1451aa4640c795b971ae9199456c)", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "particularYear", value = "指标体系年份", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult listDataByCode(String code, String divisionCode, String year, String orgId, String keyword, String particularYear) {
        //获取根据编码获取体系类型
        IdtIndicatorsType one = iIdtIndicatorsTypeService.findByCode(code, particularYear, divisionCode);
        if(null == one){
            return new AjaxResult();
        }
        //获取父节点下的所有数据
        List<ApiIdtIndicatorsDir> treeList = idtIndicatorsDirService.listDirByCode(one.getId(), null, null);
        if(treeList.size() == 0){
            return new AjaxResult();
        }
        //按关键字（名称）过滤最后一级
        if (StringUtils.isNotBlank(keyword)) {
            Iterator<ApiIdtIndicatorsDir> iterator = treeList.iterator();
            while (iterator.hasNext()) {
                ApiIdtIndicatorsDir idtDir = iterator.next();
                if (idtDir.getType() == 2) {
                    if (!idtDir.getName().contains(keyword)) {
                        iterator.remove();
                        continue;
                    }
                }
            }
        }

        idtIndicatorsDirService.formatApiIndicatorsValList(treeList, year, divisionCode);
        /*for (ApiIdtIndicatorsDir idtDir : treeList) {
            if (idtDir.getType() == 2) {
                List<ApiIndicatorsVal> apiIndicatorsValList = new ArrayList<>();
                String[] years = year.split(",");
                for (String y : years) {
                    ApiIndicatorsVal apiIndicatorsVal = iIdtIndicatorsService.listDataByCode(idtDir.getIndicatorsId(), y, area_code);
                    apiIndicatorsValList.add(apiIndicatorsVal);
                }
                idtDir.setApiIndicatorsValList(apiIndicatorsValList);
            }
        }*/
        //创建树形结构
        List tree = createTree(one.getId(), treeList);
        return new AjaxResult(tree);
    }

    /**
     * @描述：获取现状评估指标数据
     * @作者：彭辉
     * @日期：2020/12/8 16:12
     **/
    @PostMapping("/listCurrentAssessmentData")
    @ApiOperation(value = "获取现状评估指标数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "指标体系编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "year", value = "年份", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "行政区划代码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "orgId", value = "单位id", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "keywords", value = "关键字", required = false, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "particularYear", value = "指标体系年份", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult listCurrentAssessmentData(String code, Integer year, String divisionCode, String orgId, String keywords, String particularYear) {
        // 获取根据编码获取体系类型
        IdtIndicatorsType one = iIdtIndicatorsTypeService.findByCode(code, particularYear, divisionCode);
        if(null == one){
            return new AjaxResult();
        }
        // 获取父节点下的所有数据
        List<ApiIdtIndicatorsDir> allList = idtIndicatorsDirService.listDirByCode(one.getId(), null, null);
        // 存储指标id
        List<String> indicatorsIdList = new ArrayList<String>();
        // 按关键字（名称）过滤最后一级
        if (StringUtils.isNotBlank(keywords)) {
            Iterator<ApiIdtIndicatorsDir> iterator = allList.iterator();
            while (iterator.hasNext()) {
                ApiIdtIndicatorsDir idtDir = iterator.next();
                if (idtDir.getType() == 2) {
                    if (!idtDir.getName().contains(keywords)) {
                        iterator.remove();
                        continue;
                    }
                }
            }
        }

        Map<String, String> dictMap = iRedisDictService.getItemMaps("datasource");
        for (ApiIdtIndicatorsDir indicatorsDir : allList) {
            if (indicatorsDir.getType() == 2) {
                // indicatorsDir.setIdtDatasource(iRedisDictService.getText("datasource", indicatorsDir.getIdtDatasource()));
                indicatorsDir.setIdtDatasource(dictMap.get(indicatorsDir.getIdtDatasource()));
                indicatorsIdList.add(indicatorsDir.getIndicatorsId());
            }
        }

        // 根据指标体系编码、年份查询指标数值
        List<ApiIndicatorsValue> indicatorsValueList = idtReportValueService.listCurrentAssessmentData(year, divisionCode, indicatorsIdList);

        List<ApiIdtIndicatorsDir> treeList = new ArrayList<ApiIdtIndicatorsDir>();
        for (ApiIdtIndicatorsDir indicatorsDirs : allList) {
            if (indicatorsDirs.getParentId().equals(one.getId())) {
                recursiveIndicatorsData(indicatorsDirs, allList, indicatorsValueList);
                treeList.add(indicatorsDirs);
            }
        }
        return new AjaxResult(treeList);
    }

    /**
     * @描述：递归获取指标体系、指标数值
     * @作者：彭辉
     * @日期：2020/12/8 18:20
     **/
    private void recursiveIndicatorsData(ApiIdtIndicatorsDir currentIndicatorsDir, List<ApiIdtIndicatorsDir> allList, List<ApiIndicatorsValue> indicatorsValueList) {
        List<ApiIdtIndicatorsDir> children = new ArrayList<ApiIdtIndicatorsDir>();
        for (ApiIdtIndicatorsDir indicatorsDir : allList) {
            if (indicatorsDir.getParentId().equals(currentIndicatorsDir.getId())) {
                children.add(indicatorsDir);

                if (indicatorsDir.getType() == 1) {
                    recursiveIndicatorsData(indicatorsDir, allList, indicatorsValueList);
                } else {
                    for (ApiIndicatorsValue indicatorsValue : indicatorsValueList) {
                        if (indicatorsDir.getIndicatorsId().equals(indicatorsValue.getId())) {
                            indicatorsDir.setApiIndicatorsValue(indicatorsValue);
                            break;
                        }
                    }
                }
            }
        }
        currentIndicatorsDir.setChildren(children);
    }

    /**
     * @描述: 成果上报导出Excel
     * @入参:
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2020/11/5 16:47
     **/
    @PostMapping("/exportExcel")
    @ApiOperation(value = "成果上报导出Excel")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "指标体系编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "isQueryValue", value = "是否查询指标数值", required = true, dataType = "boolean", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "区域编码（查询指标数值时需要传）", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "divisionName", value = "区域名称", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "year", value = "指标数值年份（查询指标数值时需要传）", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "orgId", value = "机构id", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "exportType", value = "导出类型(1:规划值 2:上报值)", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "particularYear", value = "指标体系年份", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult exportExcel(String code, boolean isQueryValue, String divisionCode, String year, String orgId, Integer exportType, String divisionName, String particularYear) {
        //获取根据编码获取体系类型
        IdtIndicatorsType one = iIdtIndicatorsTypeService.findByCode(code, particularYear, divisionCode);
        if(null == one){
            return new AjaxResult();
        }
        //获取父节点下的所有数据
        List<ApiIdtIndicatorsDir> treeList = idtIndicatorsDirService.listDirByCode(one.getId(), null, null);
        if (isQueryValue && treeList != null && treeList.size() > 0) {
            for (ApiIdtIndicatorsDir idtDir : treeList) {
                if (idtDir.getType() == 2) {
                    ApiIndicatorsVal apiIndicatorsVal = iIdtIndicatorsService.getIdtVal(idtDir.getIndicatorsId(), year, divisionCode, false, true);
                    IdtWarnRule idtWarnRule = iIdtWarnRuleService.listWarnRuleById(idtDir.getIndicatorsId());
                    if (null != idtWarnRule) {
                        apiIndicatorsVal.setWarnRule(idtWarnRule.getName());
                    } else {
                        apiIndicatorsVal.setWarnRule(null);
                    }
                    idtDir.setApiIndicatorsVal(apiIndicatorsVal);
                }
            }
        }
        List<ApiIdtIndicatorsDir> idtIndicatorsDirs = treeList.stream().filter(x -> x.getType() == 2).collect(Collectors.toList());
        List<Object[]> dataList = new ArrayList<Object[]>();
        if (exportType == 1) {
            // 导出规划目标表
            for (ApiIdtIndicatorsDir apiIdtIndicatorsDir : idtIndicatorsDirs) {
                Object[] datas = new Object[9];
                datas[0] = apiIdtIndicatorsDir.getIdtCode();
                datas[1] = apiIdtIndicatorsDir.getIdtName();
                datas[2] = apiIdtIndicatorsDir.getIdtUnit();
                datas[3] = apiIdtIndicatorsDir.getApiIndicatorsVal().getDivisionName();
                datas[4] = apiIdtIndicatorsDir.getApiIndicatorsVal().getDivisionCode();
                datas[5] = apiIdtIndicatorsDir.getApiIndicatorsVal().getBaseYear();
                datas[6] = apiIdtIndicatorsDir.getApiIndicatorsVal().getBaseValue();
                datas[7] = apiIdtIndicatorsDir.getApiIndicatorsVal().getTargetYear();
                datas[8] = apiIdtIndicatorsDir.getApiIndicatorsVal().getTargetValue();
                datas[9] = apiIdtIndicatorsDir.getApiIndicatorsVal().getTargetExplain();
                dataList.add(datas);
            }
            // 导出Excel
            String[] titles = {"指标编号", "指标名称", "单位", "行政区划名称", "行政区划代码", "基期年份", "基期值", "规划目标年", "规划目标值", "指标说明"};
            HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
            response.setHeader("Content-type", "text/html;charset=UTF-8");
            response.setCharacterEncoding("UTF-8");
            ExcelUtil.exportExcel(response, "规划指标", "规划指标信息", titles, dataList);
        } else {
            // 导出评估指标表
            for (ApiIdtIndicatorsDir apiIdtIndicatorsDir : idtIndicatorsDirs) {
                Object[] datas = new Object[9];
                datas[0] = apiIdtIndicatorsDir.getIdtCode();
                datas[1] = apiIdtIndicatorsDir.getIdtName();
                datas[2] = apiIdtIndicatorsDir.getIdtUnit();
                datas[3] = apiIdtIndicatorsDir.getApiIndicatorsVal().getDivisionName();
                datas[4] = apiIdtIndicatorsDir.getApiIndicatorsVal().getDivisionCode();
                datas[5] = apiIdtIndicatorsDir.getApiIndicatorsVal().getYear();
                datas[6] = apiIdtIndicatorsDir.getApiIndicatorsVal().getValue();
                datas[7] = apiIdtIndicatorsDir.getApiIndicatorsVal().getReportExplain();
                dataList.add(datas);
            }
            // 导出Excel
            String[] titles = {"指标编号", "指标名称", "单位", "行政区划名称", "行政区划代码", "年份", "上报值", "指标说明"};
            HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
            response.setHeader("Content-type", "text/html;charset=UTF-8");
            response.setCharacterEncoding("UTF-8");
            ExcelUtil.exportExcel(response, "评估指标", "评估指标信息", titles, dataList);
        }
        return new AjaxResult();
    }

    /**
     * @描述:查询各个指标各下级城市指标数据
     * @入参:
     * @出参:
     * @作者: 郑文彬
     * @日期: 2020/6/29 15:40
     **/
    @PostMapping("/listIndicatorsCityTree")
    @ApiOperation(value = "查询各个指标各下级城市指标数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "指标体系编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "区域编码", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "year", value = "指标数值年份（查询指标数值时需要传）", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "queryIndicators", value = "是否查询二级指标", dataType = "boolean", paramType = "query"),
            @ApiImplicitParam(name = "orgId", value = "机构id(154a01c32b9845169fa5f9968e549203)", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "particularYear", value = "指标体系年份", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult listIndicatorsCityTree(String code, String divisionCode, String year, String orgId, boolean queryIndicators, String particularYear) {
        //获取根据编码获取体系类型
        IdtIndicatorsType one = iIdtIndicatorsTypeService.findByCode(code, particularYear, divisionCode);
        if(null == one){
            return new AjaxResult();
        }
        //查询子城市
        PageData pageData = new PageData();
        pageData.put("parent_area_code", divisionCode);
        List<PageData> cityList = iIdtIndicatorsService.listDivisionByEntity(pageData);
        //获取指标体系数据
        List<ApiIdtIndicatorsDir> dataList = idtIndicatorsDirService.listDirByCode(one.getId(), null, null);
        List<ApiCityMedical> treeList = new ArrayList();
        ApiIdtIndicatorsDir parent = new ApiIdtIndicatorsDir();
        parent.setId(one.getId());
        parent.setName("综合指数");
        parent.setParentId("-1");
        parent.setType(1);
        dataList.add(parent);
        for (ApiIdtIndicatorsDir idtDir : dataList) {
            ApiCityMedical apiCityMedical = new ApiCityMedical();
            BeanUtils.copyProperties(idtDir, apiCityMedical);
            String indicatorsId;
            if (idtDir.getType() == 2) {
                if (!queryIndicators) {
                    continue;
                }
                indicatorsId = idtDir.getIndicatorsId();
                apiCityMedical.setUnit(idtDir.getIdtUnit());
            } else {
                //给目录也配了个指标，根据目录名称查询该目录的指标
                LambdaQueryWrapper<IdtIndicators> lambda2 = new QueryWrapper().lambda();
                lambda2.eq(IdtIndicators::getName, idtDir.getName());
                IdtIndicators indicators = iIdtIndicatorsService.getOne(lambda2);
                indicatorsId = indicators.getId();
                apiCityMedical.setIndicatorsId(indicatorsId);
                apiCityMedical.setUnit(indicators.getUnit());
                //设置一级指标的同级城市排名
                ranking(apiCityMedical, divisionCode, year);
            }
            List cityListVal = new ArrayList();

            //查询当前城市的监测值
            LambdaQueryWrapper<IdtMonitorValue> lambda1 = new QueryWrapper().lambda();
            lambda1.eq(IdtMonitorValue::getIndicatorsId, indicatorsId);
            lambda1.eq(IdtMonitorValue::getYear, Integer.valueOf(year));
            lambda1.eq(IdtMonitorValue::getDivisionCode, divisionCode);
            lambda1.orderByDesc(IdtMonitorValue::getYear, IdtMonitorValue::getMonitorTime);
            List<IdtMonitorValue> list = iIdtMonitorValueService.list(lambda1);
            if (list != null && list.size() > 0) {
                IdtMonitorValue monitorValue = list.get(0);
                apiCityMedical.setValue(monitorValue.getMonitorValue());
            }
            //查询各下级城市的监测值
            float sum = 0;
            for (PageData city : cityList) {
                String cityCode = city.getString("code");
                String cityName = city.getString("name");
                //查询监测值
                LambdaQueryWrapper<IdtMonitorValue> lambda2 = new QueryWrapper().lambda();
                lambda2.eq(IdtMonitorValue::getIndicatorsId, indicatorsId);
                lambda2.eq(IdtMonitorValue::getDivisionCode, cityCode);
                lambda2.eq(IdtMonitorValue::getYear, Integer.valueOf(year));
                lambda2.orderByDesc(IdtMonitorValue::getYear, IdtMonitorValue::getMonitorTime);
                List<IdtMonitorValue> list2 = iIdtMonitorValueService.list(lambda2);
                if (list2 != null && list2.size() > 0) {
                    IdtMonitorValue monitorValue = list2.get(0);
                    HashMap<String, String> map = new HashMap<>();
                    map.put("area", cityName);
                    map.put("value", monitorValue.getMonitorValue());
                    cityListVal.add(map);
                    try {
                        sum = sum + Float.parseFloat(monitorValue.getMonitorValue());
                    } catch (Exception e) {
                    }
                }
            }
            //平均值
            apiCityMedical.setCityAvgValue(sum / cityList.size() + "");

            apiCityMedical.setCityListVal(cityListVal);
            treeList.add(apiCityMedical);
        }
        List tree2 = createTree2("-1", treeList);
        return new AjaxResult(tree2);
    }


    /**
     * @描述:listIndicatorsYearTree
     * @入参:
     * @出参:
     * @作者: 郑文彬
     * @日期: 2020/6/29 15:40
     **/
    @PostMapping("/listIndicatorsYearTree")
    @ApiOperation(value = "查询各个指标各年份的指标数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "指标体系编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "区域编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "year", value = "指标数值年份（查询指标数值时需要传）", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "orgId", value = "机构id", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "particularYear", value = "指标体系年份", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult listIndicatorsYearTree(String code, String divisionCode, String year, String orgId, String particularYear) {
        //查询同级城市 用于获取平均值
        PageData pageData = new PageData();
        pageData.put("area_code", divisionCode);
        pageData.put("arealist", Arrays.asList(divisionCode.split(",")));
        List<PageData> divisionList = iIdtIndicatorsService.listDivisionByEntity(pageData);
        //获取当前城市的父城市
        String parent_area_code = divisionList.get(0).getString("parent_code");
        //查询同级城市
        PageData pageData1 = new PageData();
        pageData1.put("parent_area_code", parent_area_code);
        List<PageData> cityList = iIdtIndicatorsService.listDivisionByEntity(pageData1);
        List cityCodeList = new ArrayList();
        for (int i = 0; i < cityList.size(); i++) {
            cityCodeList.add(cityList.get(i).getString("code"));
        }
        //获取根据编码获取体系类型
        IdtIndicatorsType one = iIdtIndicatorsTypeService.findByCode(code, particularYear, divisionCode);
        if(null == one){
            return new AjaxResult();
        }
        //获取指标体系数据
        List<ApiIdtIndicatorsDir> dataList = idtIndicatorsDirService.listDirByCode(one.getId(), null, null);
        List<ApiCityMedical> treeList = new ArrayList();
        for (ApiIdtIndicatorsDir idtDir : dataList) {
            ApiCityMedical apiCityMedical = new ApiCityMedical();
            BeanUtils.copyProperties(idtDir, apiCityMedical);
            if (idtDir.getType() == 2) {
                String indicatorsId = idtDir.getIndicatorsId();
                apiCityMedical.setUnit(idtDir.getIdtUnit());
                List cityListVal = new ArrayList();
                //查询当前城市的监测值
                LambdaQueryWrapper<IdtMonitorValue> lambda1 = new QueryWrapper().lambda();
                lambda1.eq(IdtMonitorValue::getIndicatorsId, indicatorsId);
                lambda1.eq(IdtMonitorValue::getYear, Integer.valueOf(year));
                lambda1.eq(IdtMonitorValue::getDivisionCode, divisionCode);
                lambda1.orderByDesc(IdtMonitorValue::getYear, IdtMonitorValue::getMonitorTime);
                List<IdtMonitorValue> list = iIdtMonitorValueService.list(lambda1);
                if (list != null && list.size() > 0) {
                    IdtMonitorValue monitorValue = list.get(0);
                    apiCityMedical.setValue(monitorValue.getMonitorValue());
                }

                for (int yearNum = 2010; yearNum < 2020; yearNum++) {
                    //查询监测值
                    LambdaQueryWrapper<IdtMonitorValue> lambda2 = new QueryWrapper().lambda();
                    lambda2.eq(IdtMonitorValue::getIndicatorsId, indicatorsId);
                    lambda2.eq(IdtMonitorValue::getDivisionCode, divisionCode);
                    lambda2.eq(IdtMonitorValue::getYear, yearNum);
                    lambda2.orderByDesc(IdtMonitorValue::getYear, IdtMonitorValue::getMonitorTime);
                    List<IdtMonitorValue> list2 = iIdtMonitorValueService.list(lambda2);
                    String value = null;
                    if (list2 != null && list2.size() > 0) {
                        IdtMonitorValue monitorValue = list2.get(0);
                        value = monitorValue.getMonitorValue();
                    }
                    //查询平均值
                    LambdaQueryWrapper<IdtMonitorValue> lambda3 = new QueryWrapper().lambda();
                    lambda3.eq(IdtMonitorValue::getIndicatorsId, indicatorsId);
                    lambda3.in(IdtMonitorValue::getDivisionCode, cityCodeList);
                    lambda3.eq(IdtMonitorValue::getYear, yearNum);
                    List<IdtMonitorValue> list3 = iIdtMonitorValueService.list(lambda3);
                    String avg = null;
                    if (list3 != null && list3.size() > 0) {
                        double sum = 0;
                        for (int i = 0; i < list3.size(); i++) {
                            sum = sum + Double.valueOf(list3.get(i).getMonitorValue());
                        }
                        avg = (sum / list3.size()) + "";
                    }
                    HashMap<String, String> map = new HashMap<>();
                    map.put("year", yearNum + "");
                    map.put("value", value);
                    map.put("avg", avg);
                    cityListVal.add(map);
                }
                apiCityMedical.setCityListVal(cityListVal);
            } else {
                //给目录也配了个指标，根据目录名称查询该目录的指标
                LambdaQueryWrapper<IdtIndicators> lambda2 = new QueryWrapper().lambda();
                lambda2.eq(IdtIndicators::getName, idtDir.getName());
                IdtIndicators indicators = iIdtIndicatorsService.getOne(lambda2);
                apiCityMedical.setIndicatorsId(indicators.getId());
                apiCityMedical.setUnit(indicators.getUnit());
                //查询监测值
                LambdaQueryWrapper<IdtMonitorValue> lambda3 = new QueryWrapper().lambda();
                lambda3.eq(IdtMonitorValue::getIndicatorsId, indicators.getId());
                lambda3.eq(IdtMonitorValue::getDivisionCode, divisionCode);
                lambda3.eq(IdtMonitorValue::getYear, Integer.valueOf(year));
                lambda3.orderByDesc(IdtMonitorValue::getYear, IdtMonitorValue::getMonitorTime);
                List<IdtMonitorValue> list2 = iIdtMonitorValueService.list(lambda3);
                if (list2 != null && list2.size() > 0) {
                    IdtMonitorValue monitorValue = list2.get(0);
                    apiCityMedical.setValue(monitorValue.getMonitorValue());
                }
                //设置一级指标的同级城市排名
                ranking(apiCityMedical, divisionCode, year);
            }

            treeList.add(apiCityMedical);
        }
        List tree2 = createTree2(one.getId(), treeList);
        return new AjaxResult(tree2);
    }

    /**
     * @描述:监测评估预警-动态监测
     * @入参:
     * @出参:
     * @作者: 郑文彬
     * @日期: 2020/6/30 9:56
     **/
    @PostMapping("/listIndicatorsMonitorByCode")
    @ApiOperation(value = "监测评估预警-动态监测")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "指标体系编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "区域编码（查询指标数值时需要传）", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "orgId", value = "机构id(154a01c32b9845169fa5f9968e549203)", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "particularYear", value = "指标体系年份", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult listIndicatorsMonitorByCode(String code, String divisionCode, String orgId, String particularYear) {
        if (StringUtils.isBlank(code)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "请传入体系编码");
        }
        if (StringUtils.isBlank(orgId)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "请传入机构id");
        }
        if (StringUtils.isBlank(divisionCode)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "区域编码必传");
        }
        //获取根据编码获取体系类型
        IdtIndicatorsType one = iIdtIndicatorsTypeService.findByCode(code, particularYear, divisionCode);
        if(null == one){
            return new AjaxResult();
        }
        //获取父节点下的所有数据
        List<ApiIdtIndicatorsDir> treeList = idtIndicatorsDirService.listDirByCode(one.getId(), null, null);
        if (treeList != null && treeList.size() > 0) {
            for (ApiIdtIndicatorsDir idtDir : treeList) {
                if (idtDir.getType() == 2) {
                    ApiIndicatorsVal apiIndicatorsVal = new ApiIndicatorsVal();
                    apiIndicatorsVal.setId(idtDir.getIndicatorsId());
                    apiIndicatorsVal.setName(idtDir.getIdtName());
                    apiIndicatorsVal.setUnit(idtDir.getIdtUnit());
                    //查询监测值
                    LambdaQueryWrapper<IdtMonitorValue> lambda1 = new QueryWrapper().lambda();
                    lambda1.eq(IdtMonitorValue::getIndicatorsId, idtDir.getIndicatorsId());
                    lambda1.eq(IdtMonitorValue::getDivisionCode, divisionCode);
                    lambda1.orderByDesc(IdtMonitorValue::getYear, IdtMonitorValue::getMonitorTime);
                    List<IdtMonitorValue> list = iIdtMonitorValueService.list(lambda1);
                    if (list != null && list.size() > 0) {
                        // 取最新时间的 也就是第一个
                        IdtMonitorValue idtMonitorValue = list.get(0);
                        apiIndicatorsVal.setMonitorYear(idtMonitorValue.getYear() + "");
                        apiIndicatorsVal.setMonitorValue(idtMonitorValue.getMonitorValue());
                        apiIndicatorsVal.setUpdateDate(idtMonitorValue.getModifyTime());
                        apiIndicatorsVal.setDivisionCode(idtMonitorValue.getDivisionCode());
                        apiIndicatorsVal.setWarnStatus(idtMonitorValue.getWarnStatus());
                        if (list.size() > 2) {
                            //判断是否上升
                            if (Float.parseFloat(list.get(0).getMonitorValue()) > Float.parseFloat(list.get(1).getMonitorValue())) {
                                apiIndicatorsVal.setGoUp(1);
                            } else if (Float.parseFloat(list.get(0).getMonitorValue()) < Float.parseFloat(list.get(1).getMonitorValue())) {
                                apiIndicatorsVal.setGoUp(-1);
                            }
                        }
                    }
                    // 指标监测值
                    idtDir.setApiIndicatorsVal(apiIndicatorsVal);
                }
            }
        }
        //指标更新方式
        int dynamic = 0;
        int regular = 0;
        int year = 0;
        //遍历统计
        if (treeList != null && treeList.size() > 0) {
            for (ApiIdtIndicatorsDir idtDir : treeList) {
                //2表是指标
                if (idtDir.getType() == 2) {
                    if ("dynamic".equals(idtDir.getIdtUpdateCycle())) {
                        dynamic = dynamic + 1;
                    } else if ("regular".equals(idtDir.getIdtUpdateCycle())) {
                        regular = regular + 1;
                    } else if ("year".equals(idtDir.getIdtUpdateCycle())) {
                        year = year + 1;
                    }
                }
            }
        }
        Map<String, Integer> updateCycle = new HashMap<>();
        updateCycle.put("动态更新", dynamic);
        updateCycle.put("定期更新", regular);
        updateCycle.put("年度更新", year);

        List<ApiIdtIndicatorsDir> newMonitor = new ArrayList<>();
        //按时间排序 如果是最近一个月更新的数据或者前十条数据标记为新
        if (treeList != null && treeList.size() > 0) {
            //按时间排序
            listSort(treeList);
            int num = 0;
            for (int i = 0; i < treeList.size(); i++) {
                ApiIdtIndicatorsDir idtIndicatorsDir = treeList.get(i);
                ApiIndicatorsVal apiIndicatorsVal = idtIndicatorsDir.getApiIndicatorsVal();
                if (idtIndicatorsDir.getType() == 2 && apiIndicatorsVal != null && apiIndicatorsVal.getUpdateDate() != null) {
                    if (num < 10) {
                        //取监测值更新时间最近的十条数据标记为新
                        apiIndicatorsVal.setIsNew(1);
                        newMonitor.add(idtIndicatorsDir);
                        num = num + 1;
                    } else if ((System.currentTimeMillis() - apiIndicatorsVal.getUpdateDate().getTime()) > 1000 * 60 * 60 * 24 * 30) {
                        //超过十条的更新时间为最近一个月的也标记为新
                        apiIndicatorsVal.setIsNew(1);
                        newMonitor.add(idtIndicatorsDir);
                    }
                }
            }
        }
        PageData pageData = new PageData();
        pageData.put("newMonitor", newMonitor);
        try {
            //按指标体系配置顺序排序
            treeList = treeList.stream().sorted(Comparator.comparing(ApiIdtIndicatorsDir::getSort)).collect(Collectors.toList());
        } catch (Exception e) {
            e.printStackTrace();
        }
        //创建树形结构
        List tree = createTree(one.getId(), treeList);
        pageData.put("updateCycle", updateCycle);
        pageData.put("tree", tree);
        return new AjaxResult(pageData);
    }

    /**
     * @描述:统计某指标体系各个类型指标数量
     * @入参:
     * @出参:
     * @作者: 郑文彬
     * @日期: 2020/6/29 15:40
     **/
    @PostMapping("/countTypeByCode")
    @ApiOperation(value = "统计某指标体系各个类型指标数量")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "指标体系编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "particularYear", value = "指标体系年份", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "行政区划代码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "orgId", value = "机构id(154a01c32b9845169fa5f9968e549203)", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult countTypeByCode(String code, String orgId, String divisionCode, String particularYear) {
        if (StringUtils.isBlank(orgId)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "请传入机构点");
        }
        if (StringUtils.isBlank(code)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "请传入编码点");
        }
        //获取根据编码获取体系类型
        IdtIndicatorsType one = iIdtIndicatorsTypeService.findByCode(code, particularYear, divisionCode);
        if(null == one){
            return new AjaxResult();
        }
        //获取父节点下的所有数据
        List<IdtIndicatorsDir> treeList = idtIndicatorsDirService.getAllByParentId(one.getId(), null);
        // 监测指标类型
        int basic = 0;
        int place = 0;
        int recommend = 0;
        int count = 0;
        //遍历统计
        if (treeList != null && treeList.size() > 0) {
            for (IdtIndicatorsDir idtDir : treeList) {
                //2表是指标
                if (idtDir.getType() == 2) {
                    if ("basic".equals(idtDir.getIdtType())) {
                        basic = basic + 1;
                    } else if ("place".equals(idtDir.getIdtType())) {
                        place = place + 1;
                    } else if ("recommend".equals(idtDir.getIdtType())) {
                        recommend = recommend + 1;
                    }
                }
            }
        }
        count = basic + place + recommend;
        PageData pageData = new PageData();
        pageData.put("basic", basic);
        pageData.put("place", place);
        pageData.put("recommend", recommend);
        pageData.put("count", count);
        return new AjaxResult(pageData);
    }


//    /**
//     * @描述: 评估报表文件批量下载
//     * @入参:
//     * @出参:
//     * @作者: 汤厚韬
//     * @日期: 2020/11/3 16:18
//     **/
//    @PostMapping("/downloadAllMtrFile")
//    @ApiOperation(value = "文件批量下载")
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "reportId", value = "数据上报ID", required = true, dataType = "string", paramType = "query")
//    })
//    public void downloadAllMtrFile(String reportId, String typeCode, HttpServletResponse response){
//        List<MtrDataReport> mtrDataReports = mapClient.listMtrDataReportByWrapper(reportId);
//        String year = "";
//        String divisionCode = "";
//        if (mtrDataReports != null && mtrDataReports.size() > 0) {
//            year = mtrDataReports.get(0).getReportDate();
//            divisionCode = mtrDataReports.get(0).getDivision();
//        }
//        HSSFWorkbook reportWorkbook = iIdtValueExportService.getReportValueExcelByte(typeCode, divisionCode, year, null);
//        HSSFWorkbook targetWorkbook = iIdtValueExportService.getTargetValueExcelByte(typeCode, divisionCode, year.split("-")[0], null);
//
//
//        // 行政区划
//        String divisionText = iIdtMonitorValueService.getNameByDivisionCode(divisionCode);
//
//
//        OutputStream reportStream = null;
//        OutputStream targetStream = null;
//        File tempReportFile = null;
//        File tempTargetFile = null;
//        List<DownloadZipDto> fileNodeDTOs = new ArrayList<>();
//        try {
//            String reportFileName = divisionText+"现状评估上报数值报告（"+year+"年）";
//            String reportFileExt = ".xls";
//            tempReportFile = File.createTempFile(reportFileName, reportFileExt);
//            reportStream = new FileOutputStream(tempReportFile);
//            reportWorkbook.write(reportStream);
//
//            String tempTargetName = divisionText+"规划目标数值报告（"+year.split("-")[0]+"年）";
//            String tempTargetExt = ".xls";
//            tempTargetFile = File.createTempFile(tempTargetName, tempTargetExt);
//            targetStream = new FileOutputStream(tempTargetFile);
//            targetWorkbook.write(targetStream);
//
//            reportStream.close();
//            targetStream.close();
//
//            List<MtrFileReport> mtrFileReports = mapClient.listMtrFileReportByWrapper(reportId);
//
//            if (mtrFileReports != null && mtrFileReports.size() > 0) {
//                for (MtrFileReport mtrFileReport : mtrFileReports) {
//                    if (StringUtils.isNotBlank(mtrFileReport.getFilePath())) {
//                        DownloadZipDto zipDto = new DownloadZipDto();
//                        String group = mtrFileReport.getFilePath().substring(0, mtrFileReport.getFilePath().indexOf("/"));
//                        String fileFormat = mtrFileReport.getFilePath().substring(mtrFileReport.getFilePath().lastIndexOf(".") + 1);
//                        InputStream inputStream = FastDFSUtil.download(group, mtrFileReport.getFilePath());
//                        zipDto.setInputStream(inputStream);
//                        zipDto.setFileName(mtrFileReport.getFileName());
//                        zipDto.setFileExt(fileFormat);
//                        fileNodeDTOs.add(zipDto);
//                    }
//                }
//            }
//
//            if (tempReportFile != null) {
//                DownloadZipDto reportDto = new DownloadZipDto();
//                reportDto.setFileName(reportFileName);
//                reportDto.setFileExt(reportFileExt);
//                reportDto.setInputStream(new FileInputStream(tempReportFile));
//                fileNodeDTOs.add(reportDto);
//            }
//
//
//            if (tempTargetFile != null) {
//                DownloadZipDto targetDto = new DownloadZipDto();
//                targetDto.setFileName(tempTargetName);
//                targetDto.setFileExt(tempTargetExt);
//                targetDto.setInputStream(new FileInputStream(tempTargetFile));
//                fileNodeDTOs.add(targetDto);
//            }
//
//            if (fileNodeDTOs != null && fileNodeDTOs.size() > 0) {
//                //获取其中的一个
//                String downloadName = fileNodeDTOs.get(fileNodeDTOs.size()-1).getFileName();
//                FileUtil.downloadZip(fileNodeDTOs, downloadName);
//            }
//
//        } catch (Exception ex) {
//            ex.printStackTrace();
//        } finally {
//            try {
//                reportStream.close();
//                targetStream.close();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//            if(tempReportFile != null && tempReportFile.exists()){
//                tempReportFile.delete();
//            }
//            if(tempTargetFile != null && tempTargetFile.exists()){
//                tempTargetFile.delete();
//            }
//        }
//    }

    private void prepareData(IdtIndicatorsDir idtIndicatorsDir, boolean isSave) {
        if (isSave) {
            idtIndicatorsDir.setCreator(this.getUser().getUserId().toString());
            idtIndicatorsDir.setCreateTime(new Date());
            //防止误修改
            idtIndicatorsDir.setModifier(null);
            idtIndicatorsDir.setModifyTime(null);
        } else {
            idtIndicatorsDir.setModifier(this.getUser().getUserId().toString());
            idtIndicatorsDir.setModifyTime(new Date());
            //防止误修改
            idtIndicatorsDir.setCreator(null);
            idtIndicatorsDir.setCreateTime(null);
        }
    }

    /**
     * @描述:排序列表
     * @入参:
     * @出参:
     * @作者: 戴伙进
     * @日期: 2020/6/4 15:22
     **/
    public static void sortList(List<IdtIndicatorsDir> list, String id, List<IdtIndicatorsDir> resultList) {
        for (IdtIndicatorsDir node : list) {
            if (node.getParentId().equals(id)) {
                node.setTreeLevel(node.getTreeLevel() + 1);
                resultList.add(node);
                sortList(list, node.getId(), resultList);
            }
        }
    }

    private static void sortList(List<IdtIndicatorsDir> list, String id, List<IdtIndicatorsDir> resultList, IdtIndicatorsDir idtIndicatorsDir) {
        for (IdtIndicatorsDir node : list) {
            if (node.getParentId().equals(id)) {
                if (idtIndicatorsDir != null && idtIndicatorsDir.getTreeLevel() != null) {
                    node.setTreeLevel(idtIndicatorsDir.getTreeLevel() + 1);
                } else {
                    node.setTreeLevel(node.getTreeLevel() + 1);
                }

                resultList.add(node);
                sortList(list, node.getId(), resultList, node);
            }
        }
    }

    /**
     * @描述:递归创建树
     * @入参:
     * @出参:
     * @作者: 郑文彬
     * @日期: 2020/4/20 17:30
     **/
    public static List createTree(String parentId, List<ApiIdtIndicatorsDir> menus) {
        List tree = new ArrayList<>();
        for (int i = 0; i < menus.size(); i++) {
            ApiIdtIndicatorsDir idtDirectory = menus.get(i);
            if (idtDirectory.getParentId().equals(parentId)) {
                tree.add(idtDirectory);
                List children = createTree(idtDirectory.getId(), menus);
                if (children != null && !children.isEmpty()) {
                    idtDirectory.setChildren(children);
                } else {
                    idtDirectory.setChildren(new ArrayList<>());
                }
            }
        }
        return tree;
    }

    /**
     * @描述:递归创建树
     * @入参:
     * @出参:
     * @作者: 郑文彬
     * @日期: 2020/4/20 17:30
     **/
    public static List createTree2(String parentId, List<ApiCityMedical> menus) {
        List tree = new ArrayList<>();
        for (int i = 0; i < menus.size(); i++) {
            ApiCityMedical idtDirectory = menus.get(i);
            if (idtDirectory.getParentId().equals(parentId)) {
                tree.add(idtDirectory);
                List children = createTree2(idtDirectory.getId(), menus);
                if (children != null && !children.isEmpty()) {
                    idtDirectory.setChildren(children);
                }
            }
        }
        return tree;
    }

    /**
     * @描述:当前指标和同级城市的排名
     * @入参:
     * @出参:
     * @作者: 郑文彬
     * @日期: 2020/8/13 11:10
     **/
    private void ranking(ApiCityMedical apiCityMedical, String areaCode, String year) {
        PageData pageData = new PageData();
        pageData.put("area_code", areaCode);
        pageData.put("arealist", Arrays.asList(areaCode.split(",")));
        List<PageData> divisionList = iIdtIndicatorsService.listDivisionByEntity(pageData);
        if (divisionList.size() > 0) {
            String parent_area_code = divisionList.get(0).getString("parent_code");
            //查询同级城市
            PageData pageData1 = new PageData();
            pageData1.put("parent_area_code", parent_area_code);
            List<PageData> cityList = iIdtIndicatorsService.listDivisionByEntity(pageData1);

            //今年各个城市数值
            List<Map<String, String>> cityListVal = new ArrayList<>();
            for (PageData city : cityList) {
                String cityCode = city.getString("code");
                //查询监测值
                LambdaQueryWrapper<IdtMonitorValue> lambda2 = new QueryWrapper().lambda();
                lambda2.eq(IdtMonitorValue::getIndicatorsId, apiCityMedical.getIndicatorsId());
                lambda2.eq(IdtMonitorValue::getDivisionCode, cityCode);
                lambda2.eq(IdtMonitorValue::getYear, Integer.valueOf(year));
                lambda2.orderByDesc(IdtMonitorValue::getYear, IdtMonitorValue::getMonitorTime);
                List<IdtMonitorValue> list2 = iIdtMonitorValueService.list(lambda2);
                if (list2 != null && list2.size() > 0) {
                    IdtMonitorValue monitorValue = list2.get(0);
                    HashMap<String, String> map = new HashMap<>();
                    map.put("code", cityCode);
                    map.put("value", monitorValue.getMonitorValue());
                    cityListVal.add(map);
                }
            }

            //去年各个城市数值
            List<Map<String, String>> cityListVal2 = new ArrayList<>();
            for (PageData city : cityList) {
                String cityCode = city.getString("code");
                //查询监测值
                LambdaQueryWrapper<IdtMonitorValue> lambda2 = new QueryWrapper().lambda();
                lambda2.eq(IdtMonitorValue::getIndicatorsId, apiCityMedical.getIndicatorsId());
                lambda2.eq(IdtMonitorValue::getDivisionCode, cityCode);
                lambda2.eq(IdtMonitorValue::getYear, Integer.valueOf(year) - 1);
                lambda2.orderByDesc(IdtMonitorValue::getYear, IdtMonitorValue::getMonitorTime);
                List<IdtMonitorValue> list2 = iIdtMonitorValueService.list(lambda2);
                if (list2 != null && list2.size() > 0) {
                    IdtMonitorValue monitorValue = list2.get(0);
                    HashMap<String, String> map = new HashMap<>();
                    map.put("code", cityCode);
                    map.put("value", monitorValue.getMonitorValue());
                    cityListVal2.add(map);
                }
            }

            //排序
            Collections.sort(cityListVal, new Comparator<Map<String, String>>() {
                @Override
                public int compare(Map<String, String> o1, Map<String, String> o2) {
                    String date1 = o1.get("value");
                    String date2 = o2.get("value");
                    return date2.compareTo(date1);
                }
            });
            //排序
            Collections.sort(cityListVal2, new Comparator<Map<String, String>>() {
                @Override
                public int compare(Map<String, String> o1, Map<String, String> o2) {
                    String date1 = o1.get("value");
                    String date2 = o2.get("value");
                    return date2.compareTo(date1);
                }
            });

            //获取今年排名
            for (int i = 0; i < cityListVal.size(); i++) {
                if (areaCode.equals(cityListVal.get(i).get("code"))) {
                    apiCityMedical.setRanking1(i + 1);
                }
            }
            //获取去年排名
            for (int i = 0; i < cityListVal2.size(); i++) {
                if (areaCode.equals(cityListVal2.get(i).get("code"))) {
                    apiCityMedical.setRanking2(i + 1);
                }
            }
        }

    }

    /**
     * 根据时间排序
     *
     * @param list
     */
    private static void listSort(List<ApiIdtIndicatorsDir> list) {
        Collections.sort(list, new Comparator<ApiIdtIndicatorsDir>() {
            @Override
            public int compare(ApiIdtIndicatorsDir o1, ApiIdtIndicatorsDir o2) {
                try {
                    if (o1 == null || o1.getApiIndicatorsVal() == null || o1.getApiIndicatorsVal().getUpdateDate() == null) {
                        return 1;
                    }
                    if (o2 == null || o2.getApiIndicatorsVal() == null || o1.getApiIndicatorsVal().getUpdateDate() == null) {
                        return -1;
                    }
                    Date dt1 = o1.getApiIndicatorsVal().getUpdateDate();
                    Date dt2 = o2.getApiIndicatorsVal().getUpdateDate();
                    if (dt2 == null || dt1.getTime() > dt2.getTime()) {
                        return -1;
                    } else if (dt1 == null || dt1.getTime() < dt2.getTime()) {
                        return 1;
                    } else {
                        return 0;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return 0;
            }
        });
    }

    /**
     * @描述: 指标预警清单列表数据
     * @入参:
     * @出参:
     * @作者: lzy
     * @日期: 2023/4/7 10:07
     **/
    @PostMapping("/warnListByCode")
    @ApiOperation(value = "指标预警清单列表数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "指标体系编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "区域编码", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "year", value = "年份", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "type", value = "统计类型[0指标维度  1地区维度]", dataType = "string", paramType = "query")
    })
    public R warnListByCode(String code, String divisionCode, String year, String type){
        Map map = idtIndicatorsDirService.warnListByCode(code,divisionCode,year,type);
        return R.data(map);
    }

    /**
     * @描述: 指标预警清单地图数据
     * @入参:
     * @出参:
     * @作者: lzy
     * @日期: 2023/4/7 10:07
     **/
    @PostMapping("/idtListByCodeAndYear")
    @ApiOperation(value = "指标预警清单地图数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "指标体系编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "区域编码", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "year", value = "年份", dataType = "string", paramType = "query"),
    })
    public R idtListByCodeAndYear(String code, String divisionCode, String year){
        List list = idtIndicatorsDirService.idtListByCodeAndYear(code,divisionCode,year);
        return R.data(list);
    }

    /**
     * @描述: 获取评估结果数据
     * @入参:
     * @出参:
     * @作者: lzy
     * @日期: 2023/5/25 14:45
     **/
    @PostMapping("/getEstimateResults")
    @ApiOperation(value = "获取评估结果数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "指标体系编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "区域编码", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "year", value = "年份", dataType = "string", paramType = "query"),
    })
    public R getEstimateResults(String code, String divisionCode, String year){
        if(StringUtils.isBlank(divisionCode) || StringUtils.isBlank(year)){
            return R.fail("区域编码或年份必传");
        }
        List<IdtEstimateResultDto> list = this.idtIndicatorsDirService.getEstimateResults(code,divisionCode,year);
        return R.data(list);
    }
}
